home *** CD-ROM | disk | FTP | other *** search
- (*************************************************************************
-
- $RCSfile: RKMButtonclass.mod $
- Description: Example Boopsi gadget for RKRM:Libraries
-
- Created by: fjc (Frank Copeland)
- $Revision: 1.4 $
- $Author: fjc $
- $Date: 1995/07/02 16:59:58 $
-
- Copyright © 1994-1995, Frank Copeland.
- This example program is part of Oberon-A.
- See Oberon-A.doc for conditions of use and distribution.
-
- Log entries are at the end of the file.
-
- *************************************************************************)
-
- <* STANDARD- *> <*$ NilChk- StackChk- *>
-
- MODULE RKMButtonclass;
-
- IMPORT
- SYS := SYSTEM,
- Kernel,
- e := Exec,
- i := Intuition,
- u := Utility,
- gfx := Graphics,
- cf := ClassFace,
- IE := InputEvent,
- Errors,
- d := Dos;
-
- CONST
- VersionTag = "$VER: RKMButtonclass 1.4 (4.6.95)\r\n";
- VersionStr = "RKMButtonclass 1.4 (4.6.95)\r\n";
- CopyrightStr = "Copyright © 1994-1995 Frank Copeland";
-
- (*
- ** Class specifics
- *)
-
- CONST
-
- rkmButPulse = u.user + 1;
-
- TYPE
-
- ButINSTPtr = POINTER [2] TO ButINST;
- ButINST = RECORD [2]
- midX, midY : LONGINT; (* Co-ordinates of middle of gadget *)
- END;
-
- CONST
-
- (* ButINST has one flag: *)
-
- eraseOnly = 0; (* Tells rendering routine to *)
- (* only erase the gadget, not *)
- (* rerender a new one. This *)
- (* lets the gadget erase it- *)
- (* self before it rescales. *)
-
- (**************************************************************************)
- (* The Main procedure connects an RKMButClass object to a Boopsi integer *)
- (* gadget, which displays the RKMButClass gadget's rkmButPulse value. *)
- (* The code scales and moves the gadget while it is in place. *)
- (**************************************************************************)
-
- VAR
-
- pulse2int : ARRAY 2 OF u.TagItem;
-
- CONST
-
- intWidth = 40;
- intHeight = 20;
-
- VAR
-
- w : i.WindowPtr;
- rkmbutcl : i.IClassPtr;
- integer, but : i.GadgetPtr;
- msg : i.IntuiMessagePtr;
-
- (*------------------------------------*)
- PROCEDURE^ freeRKMButGadClass ( cl : i.IClassPtr );
-
- PROCEDURE* Cleanup (VAR rc : LONGINT);
- BEGIN (* Cleanup *)
- IF but # NIL THEN
- SYS.PUTREG (0, i.RemoveGList (w, integer, -1));
- i.DisposeObject (but); but := NIL
- END;
- IF integer # NIL THEN i.DisposeObject (integer); integer := NIL END;
- IF rkmbutcl # NIL THEN freeRKMButGadClass (rkmbutcl); rkmbutcl := NIL END;
- IF w # NIL THEN i.CloseWindow (w); w := NIL END
- END Cleanup;
-
- (*------------------------------------*)
- PROCEDURE Init ();
-
- BEGIN (* Init *)
- ASSERT (u.base # NIL, 100);
- pulse2int [0].tag := rkmButPulse; pulse2int [0].data := i.stringaLongVal;
- pulse2int [1].tag := u.end;
- but := NIL; integer := NIL; rkmbutcl := NIL; w := NIL;
- Kernel.SetCleanup (Cleanup)
- END Init;
-
-
- (*------------------------------------*)
- PROCEDURE MainLoop ( attr, value : LONGINT );
-
- VAR done : BOOLEAN; ignore : LONGINT;
-
- BEGIN (* MainLoop *)
- done := FALSE;
- ignore := i.SetGadgetAttrs (but^, w, NIL, attr, value, u.done);
- WHILE ~done DO
- e.WaitPort (w.userPort);
- LOOP
- msg := SYS.VAL (i.IntuiMessagePtr, e.GetMsg (w.userPort));
- IF msg = NIL THEN EXIT END;
- IF msg.class = {i.closeWindow} THEN done := TRUE END;
- e.ReplyMsg (msg)
- END;
- END;
- END MainLoop;
-
- (*------------------------------------*)
- PROCEDURE RenderRKMBut
- ( cl : i.IClassPtr; g : i.GadgetPtr; msg : i.RenderPtr )
- : e.APTR;
-
- VAR
- inst : ButINSTPtr;
- rp : gfx.RastPortPtr;
- retval : e.APTR;
- pens : i.DRIPenArrayPtr;
- back, shine, shadow, wd, h, x, y : INTEGER;
-
- BEGIN (* RenderRKMBut *)
- inst := cf.InstData (cl, SYS.VAL (i.ObjectPtr, g));
- retval := SYS.VAL (e.APTR, e.LTRUE);
- pens := msg.gInfo.drInfo.pens;
- IF msg.msg.methodID = i.gmRender THEN (* If msg is truly a gmRender message *)
- (* (not a Input that looks like a *)
- (* Render), use the rastport within *)
- (* it... *)
- rp := msg.rPort
- ELSE (* ...Otherwise, get a rastport using *)
- (* ObtainGIRPort(). *)
- rp := i.ObtainGIRPort (msg.gInfo)
- END;
- IF rp # NIL THEN
- IF i.selected IN g.flags THEN (* If the gadget is selected, *)
- (* reverse the meanings of the *)
- (* pens. *)
- back := pens [i.fillPen];
- shine := pens [i.shadowPen];
- shadow := pens [i.shinePen]
- ELSE
- back := pens [i.backGroundPen];
- shine := pens [i.shinePen];
- shadow := pens [i.shadowPen]
- END;
- gfx.SetDrMd (rp, gfx.jam1);
-
- gfx.SetAPen (rp, SHORT (back)); (* Erase the old gadget *)
- gfx.RectFill
- ( rp, g.leftEdge,
- g.topEdge,
- g.leftEdge + g.width,
- g.topEdge + g.height );
-
- gfx.SetAPen (rp, SHORT (shadow)); (* Draw shadow edge *)
- gfx.Move (rp, g.leftEdge + 1, g.topEdge + g.height);
- gfx.Draw (rp, g.leftEdge + g.width, g.topEdge + g.height);
- gfx.Draw (rp, g.leftEdge + g.width, g.topEdge + 1);
-
- wd := g.width DIV 4; (* Draw arrows - Sorry, no frills imagery *)
- h := g.height DIV 2;
- x := g.leftEdge + (wd DIV 2);
- y := g.topEdge + (h DIV 2);
-
- gfx.Move (rp, x, SHORT (inst.midY));
- gfx.Draw (rp, x + wd, y);
- gfx.Draw (rp, x + wd, y + g.height - h);
- gfx.Draw (rp, x, SHORT (inst.midY));
-
- x := g.leftEdge + (wd DIV 2) + g.width DIV 2;
-
- gfx.Move (rp, x + wd, SHORT (inst.midY));
- gfx.Draw (rp, x, y);
- gfx.Draw (rp, x, y + g.height - h);
- gfx.Draw (rp, x + wd, SHORT (inst.midY));
-
- gfx.SetAPen (rp, SHORT (shine)); (* Draw shine edge *)
- gfx.Move (rp, g.leftEdge, g.topEdge + g.height - 1);
- gfx.Draw (rp, g.leftEdge, g.topEdge);
- gfx.Draw (rp, g.leftEdge + g.width - 1, g.topEdge);
-
- IF msg.msg.methodID # i.gmRender THEN (* If we allocated a rastport, give *)
- (* it back. *)
- i.ReleaseGIRPort (rp)
- END;
- ELSE
- retval := SYS.VAL (e.APTR, e.LFALSE);
- END;
- RETURN retval
- END RenderRKMBut;
-
-
- (*------------------------------------*)
- PROCEDURE NotifyPulse
- ( cl : i.IClassPtr;
- o : i.ObjectPtr;
- flags : SET;
- mid : LONGINT;
- gpi : i.InputPtr );
-
- VAR
- tt : ARRAY 3 OF u.TagItem;
- g : i.GadgetPtr;
- ignore : e.APTR;
-
- BEGIN (* NotifyPulse *)
- g := SYS.VAL (i.GadgetPtr, o);
-
- tt[0].tag := rkmButPulse;
- tt[0].data := mid - gpi.mouse.x + g.leftEdge;
-
- tt[1].tag := i.gaID;
- tt[1].data := g.gadgetID;
-
- tt[2].tag := u.done;
-
- ignore := cf.DoSuperMethod
- (cl, o, i.omNotify, SYS.ADR (tt), gpi.gInfo, flags)
- END NotifyPulse;
-
- (*------------------------------------*)
- PROCEDURE* dispatchRKMButGad
- ( hook : u.HookPtr; obj : e.APTR; message : e.APTR )
- : e.APTR;
-
- VAR
- cl : i.IClassPtr; o : i.ObjectPtr; msg : i.MsgPtr;
- inst : ButINSTPtr;
- retval, ignore : SYS.LONGWORD;
- object : i.ObjectPtr;
- g : i.GadgetPtr;
- gpi : i.InputPtr;
- ie : IE.InputEventPtr;
- rp : gfx.RastPortPtr;
- x, y, wd, h : INTEGER;
- pens : i.DRIPenArrayPtr;
- opSet : i.OpSetPtr;
-
- BEGIN (* dispatchRKMButGad *)
- cl := SYS.VAL (i.IClassPtr, hook);
- o := obj;
- msg := message;
- retval := e.LTRUE;
- CASE msg.methodID OF
- i.omNew : (* First, pass up to superclass *)
- object := cf.DoSuperMethodA (cl, o, msg^);
- IF object # NIL THEN
- g := SYS.VAL (i.GadgetPtr, object);
- (* Initial local instance data *)
- inst := cf.InstData (cl, object);
- inst.midX := g.leftEdge + (g.width DIV 2);
- inst.midY := g.topEdge + (g.height DIV 2);
- retval := object
- END;
- |
- i.gmHitTest :
- (* Since this is a rectangular gadget this *)
- (* method always returns i.gmrGadgetHit. *)
- retval := i.gmrGadgetHit;
- |
- i.gmGoActive :
- inst := cf.InstData (cl, o);
- (* Only become active if the gmGoActive *)
- (* was triggered by direct user input. *)
- gpi := SYS.VAL (i.InputPtr, msg);
- IF gpi.iEvent # NIL THEN
- (* This gadget is now active, change *)
- (* visual state to selected and render. *)
- g := SYS.VAL (i.GadgetPtr, o);
- INCL (g.flags, i.selected);
- ignore := RenderRKMBut (cl, g, SYS.VAL (i.RenderPtr, msg));
- retval := i.gmrMeActive
- ELSE (* The gmGoActive was not *)
- (* triggered by direct user input *)
- retval := i.gmrNoReuse
- END;
- |
- i.gmRender :
- g := SYS.VAL (i.GadgetPtr, o);
- retval := RenderRKMBut (cl, g, SYS.VAL (i.RenderPtr, msg));
- |
- i.gmHandleInput : (* While it is active, this gadget sends its *)
- (* superclass an omNotify pulse for every *)
- (* classTimer event that goes by (about one every *)
- (* 10th of a second). Any object that is *)
- (* connected to this gadget will get A LOT of *)
- (* omUpdate messages. *)
- g := SYS.VAL (i.GadgetPtr, o);
- gpi := SYS.VAL (i.InputPtr, msg);
- ie := SYS.VAL (IE.InputEventPtr, gpi.iEvent);
-
- inst := cf.InstData (cl, o);
-
- retval := i.gmrMeActive;
-
- IF ie.class = IE.rawmouse THEN
- CASE ie.code OF
- i.selectUp : (* The user let go of the gadget so return *)
- (* gmrNoReuse to deactivate and to tell *)
- (* Intuition not to reuse this Input Event as we *)
- (* have already processed it. *)
-
- (* If the user let go of the gadget while the *)
- (* mouse was over it, mask gmrVerify into the *)
- (* return value so Intuition will send a Release *)
- (* Verify (gadgetUp). *)
- IF
- (gpi.mouse.x < g.leftEdge) OR
- (gpi.mouse.x > g.leftEdge + g.width) OR
- (gpi.mouse.y < g.topEdge) OR
- (gpi.mouse.y > g.topEdge + g.height)
- THEN
- retval := i.gmrNoReuse + i.gmrVerify
- ELSE
- retval := i.gmrNoReuse
- END;
-
- (* Since the gadget is going inactive, send a final *)
- (* notification to the icaTarget *)
- NotifyPulse (cl, o, {}, inst.midX, gpi)
- |
- i.menuDown : (* The user hit the menu button. Go inactive and *)
- (* let Intuition reuse the menu button event so *)
- (* Intuition can pop up the menu bar. *)
- retval := i.gmrReuse;
- NotifyPulse (cl, o, {}, inst.midX, gpi)
- |
- ELSE
- retval := i.gmrMeActive
- END
- ELSIF ie.class = IE.timer THEN
- (* If the gadget gets a timer event, it sends an interim *)
- (* omNotify to its superclass. *)
- NotifyPulse (cl, o, {i.opuInterim}, inst.midX, gpi)
- END;
- |
- i.gmGoInactive : (* Intuition said to go inactive. Clear the *)
- (* gflgSelected bit and render using unselected *)
- (* imagery. *)
- g := SYS.VAL (i.GadgetPtr, o);
- EXCL (g.flags, i.selected);
- ignore := RenderRKMBut (cl, g, SYS.VAL (i.RenderPtr, msg));
- |
- i.omSet : (* Although this class doesn't have settable attributes, *)
- (* this gadget class does have scaleable imagery, so it *)
- (* needs to find out when its size and/or position has *)
- (* changed so it can erase itself, THEN scale, and *)
- (* rerender. *)
- opSet := SYS.VAL (i.OpSetPtr, msg);
- IF
- (u.FindTagItem (i.gaWidth, opSet.attrList) # NIL) OR
- (u.FindTagItem (i.gaHeight, opSet.attrList) # NIL) OR
- (u.FindTagItem (i.gaTop, opSet.attrList) # NIL) OR
- (u.FindTagItem (i.gaLeft, opSet.attrList) # NIL)
- THEN
- g := SYS.VAL (i.GadgetPtr, o);
-
- x := g.leftEdge;
- y := g.topEdge;
- wd := g.width;
- h := g.height;
-
- inst := cf.InstData (cl, o);
-
- retval := cf.DoSuperMethodA (cl, o, msg^);
-
- (* Get pointer to RastPort for gadget *)
- rp := i.ObtainGIRPort (opSet.gInfo);
- IF rp # NIL THEN
- pens := opSet.gInfo.drInfo.pens;
- gfx.SetAPen (rp, SHORT (pens [i.backGroundPen]));
- gfx.SetDrMd (rp, gfx.jam1); (* Erase the old gadget. *)
- gfx.RectFill (rp, x, y, x+wd, y+h);
-
- inst.midX := g.leftEdge + (g.width DIV 2); (* Recalculate where *)
- inst.midY := g.topEdge + (g.height DIV 2); (* the center of the *)
- (* gadget is. *)
-
- (* Rerender the gadget. *)
- ignore :=
- cf.DoMethod (o, i.gmRender, opSet.gInfo, rp, i.gRedrawRedraw);
- i.ReleaseGIRPort (rp)
- END;
- ELSE
- retval := cf.DoSuperMethodA (cl, o, msg^)
- END;
- |
- ELSE (* rkmbutgadclass does not recognize the methodId, let the *)
- (* superclass's dispatcher take a look at it. *)
- retval := cf.DoSuperMethodA (cl, o, msg^);
- END;
- RETURN SYS.VAL (e.APTR, retval)
- END dispatchRKMButGad;
-
- (*------------------------------------*)
- PROCEDURE initRKMButGadClass () : i.IClassPtr;
-
- VAR
- cl : i.IClassPtr;
-
- BEGIN (* initRKMButGadClass *)
- cl := i.MakeClass ( "", "gadgetclass", NIL, SIZE (ButINST), {} );
- IF cl # NIL THEN
- (* initialize the IClass Hook *)
- u.InitHook (cl, dispatchRKMButGad);
- END;
- RETURN cl
- END initRKMButGadClass;
-
-
- (*------------------------------------*)
- PROCEDURE freeRKMButGadClass ( cl : i.IClassPtr );
-
- VAR ignore : BOOLEAN;
-
- BEGIN (* freeRKMButGadClass *)
- ignore := i.FreeClass (cl)
- END freeRKMButGadClass;
-
- (*------------------------------------*)
- PROCEDURE Main ();
-
- VAR ignore : INTEGER;
-
- BEGIN (* Main *)
- IF i.base.libNode.version >= 37 THEN
- IF u.base.libNode.version >= 37 THEN
- IF gfx.base.libNode.version >= 37 THEN
- w := i.OpenWindowTagsA
- ( NIL,
- i.waFlags, { i.windowDepth, i.windowDrag,
- i.windowClose, i.windowSizing },
- i.waIDCMP, {i.closeWindow},
- i.waWidth, 640,
- i.waHeight, 200,
- u.end );
- IF w # NIL THEN
- IF i.WindowLimits (w, 450, 200, 640, 200) THEN END;
- rkmbutcl := initRKMButGadClass();
- IF rkmbutcl # NIL THEN
- integer := i.NewObject
- ( NIL, "strgclass",
- i.gaID, 1,
- i.gaTop, LONG (w.borderTop) + 5,
- i.gaLeft, LONG (w.borderLeft) + 5,
- i.gaWidth, intWidth,
- i.gaHeight, intHeight,
- i.stringaLongVal, 0,
- i.stringaMaxChars, 5,
- u.end );
- IF integer # NIL THEN
- but := i.NewObject
- ( rkmbutcl, "",
- i.gaID, 2,
- i.gaTop, LONG (w.borderTop) + 5,
- i.gaLeft, integer.leftEdge + integer.width + 5,
- i.gaWidth, 40,
- i.gaHeight, intHeight,
- i.gaPrevious, integer,
- i.icaMap, SYS.ADR (pulse2int),
- i.icaTarget, integer,
- u.end );
- IF but # NIL THEN
- ignore := i.AddGList (w, integer, -1, -1, NIL);
- i.RefreshGList (integer, w, NIL, -1);
-
- i.SetWindowTitles
- ( w, SYS.ADR ("<-- Click to resize gadget Height"), NIL );
- MainLoop (u.done, 0);
-
- i.SetWindowTitles
- ( w, SYS.ADR ("<-- Click to resize gadget Width"), NIL );
- MainLoop (i.gaHeight, 100);
-
- i.SetWindowTitles
- ( w, SYS.ADR ("<-- Click to resize gadget Y position"), NIL );
- MainLoop (i.gaWidth, 100);
-
- i.SetWindowTitles
- ( w, SYS.ADR ("<-- Click to resize gadget X position"), NIL );
- MainLoop (i.gaTop, but.topEdge + 20);
-
- i.SetWindowTitles
- ( w, SYS.ADR ("<-- Click to quit"), NIL );
- MainLoop (i.gaLeft, but.leftEdge + 20);
-
- ignore := i.RemoveGList (w, integer, -1);
- i.DisposeObject (but); but := NIL
- END;
- i.DisposeObject (integer); integer := NIL
- END;
- freeRKMButGadClass (rkmbutcl); rkmbutcl := NIL
- END;
- i.CloseWindow (w); w := NIL
- END;
- END;
- END;
- END
- END Main;
-
- BEGIN (* RKMButtonclass *)
- Errors.Init;
- Init ();
- Main ();
- END RKMButtonclass.
-